package com.sk.restree.model.action.bank;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sk.restree.components.googleplaces.GPJsonOperator;
import com.sk.restree.components.googleplaces.GPURLParam;
import com.sk.restree.components.googleplaces.GPURLParamMaker;
import com.sk.restree.components.googleplaces.GooglePlaces;
import com.sk.restree.model.dao.StoreDAO;
import com.sk.restree.model.dto.BankFeeDTO;
import com.sk.restree.model.dto.StoreDTO;

public class BenefitJsonMaker {
	private String latitude;
	private String longitude;
	private GooglePlaces gp;
	private GPJsonOperator jsOperator;

	public BenefitJsonMaker() {
		gp = new GooglePlaces();
		jsOperator = new GPJsonOperator();
	}

	public BenefitJsonMaker(HttpServletRequest request) {
		this();
		setParameter(request);
	}

	public void setParameter(HttpServletRequest request) {
		latitude = request.getParameter("latitude");
		longitude = request.getParameter("longitude");
	}

	public void response(Map<String, Object> gpMap, HttpServletResponse response) {
		try {
			jsOperator.writeValue(response.getWriter(), gpMap);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public GPURLParam getParam(String name, String types) {
		GPURLParam param = GPURLParamMaker.getInstance().getGPURLParam();
		if (name != null) {
			param.setName(name);
		}
		if (types != null) {
			param.setTypes(types);
		}
		param.setLatitude(latitude);
		param.setLongitude(longitude);
		return param;
	}

	public String getBenefitPlacesJsStrAsName(String storeName) {
		if (!check())
			return null;
		String jsonString = gp.getPlacesAsJsonString(getParam(storeName, null));
		return jsonString;
	}

	public Map<String, Object> createGPMap() {
		return jsOperator.createGPMap();
	}

	public String getBenefitPlacesJsStr(String name, String types) {
		if (!check())
			return null;
		String jsonString = gp.getPlacesAsJsonString(getParam(name, types));
		return jsonString;
	}

	private boolean check() {
		if (latitude == null || longitude == null)
			return false;
		else
			return true;
	}

	public synchronized void requestBenefitPlacesJsStrList(
			List<GPURLParam> storeList, BenefitCallback callback) {
		if (!check())
			return;
		// stroeList
		cntForCallback = storeList.size();
		listForCallback = new ArrayList<String>();
		this.callback = callback;
		for (GPURLParam gpUrlParam : storeList) {
			new BenefitThread(gpUrlParam).start();
		}
	}

	int cntForCallback;
	List<String> listForCallback = null;
	BenefitCallback callback = null;

	private synchronized void callBack(String value) {
		cntForCallback--;
		listForCallback.add(value);
		if (cntForCallback == 0) {
			callback.callback(listForCallback);
			listForCallback = null;
			callback = null;
		}
	}

	class BenefitThread extends Thread {

		GPURLParam param;

		BenefitThread(GPURLParam param) {
			this.param = param;
		}

		@Override
		public void run() {
			String returnValue = gp.getPlacesAsJsonString(param);
			callBack(returnValue);
		}
	}

	private void setMapAsResults(Map<String, Object> gpMap,
			List<Map<String, Object>> results) {
		for (Map<String, Object> result : results) {
			jsOperator.addResultElement(gpMap, result);
		}
	}

	private List<Map<String, Object>> parsejsStrToList(String jsStr) {
		return jsOperator
				.getResults(jsOperator.transformJsonStringAsMap(jsStr));
	}

	public void insertJsResultsIntoMap(Map<String, Object> gpMap,
			List<String> jslist) {
		for (String jsStr : jslist) {
			setMapAsResults(gpMap, parsejsStrToList(jsStr));
		}
	}

	public void insertJsResultsIntoMap(Map<String, Object> gpMap,
			List<String> jslist, String category) {
		for (String jsStr : jslist) {
			setMapAsResults(gpMap, parsejsStrToList(jsStr));
		}
		if (category.equals("gas_station")) {
			setID(gpMap, "gas_station");
		} else if (category.equals("movie_theater")) {
			setID(gpMap, "movie_theater");
		} else if (category.equals("restaurant")) {
			setID(gpMap, "restaurant");
		} else if (category.equals("cafe")) {
			setID(gpMap, "cafe");
		}
	}

	private void setID(Map<String, Object> gpMap, String category) {
		List<Map<String, Object>> results = jsOperator.getResults(gpMap);
		for (Map<String, Object> result : results) {
			String storeId = getStoreId((String) result.get("name"),
					category);
			result.put("storeid", storeId);
			result.put("category", category);
		}
	}

	private String getStoreId(String name, String category) {
		StoreDAO dao = StoreDAO.getIntance();
		List<StoreDTO> list = dao.getStoreList();
		for (StoreDTO stores : list) {
			if (stores.getCategory().equals(category)) {
				if (name.contains(stores.getStore_name())) {
					return stores.getStore_id();
				}
			}
		}
		return "0";
	}
}
